Namespace("org.wattdepot.gdata.makahiki");

// http://code.google.com/apis/visualization/documentation/gallery/genericimagechart.html

// Requires configuration.js and HtmlTable.js

// Creates a table showing power data from the last few minutes. 
org.wattdepot.gdata.makahiki.PowerLastFewMinutes = function(configuration) {
  var configuration = configuration;
  var width = 300;
  var height = 200;
  // Note: generic image chart can accept colors with or without a hash.
  var greenColor = configuration.greenIndicatorColor.replace('#', '');
  var redColor = configuration.redIndicatorColor.replace('#', '');
  var textColor = configuration.widgetTextColor.replace('#', '');
  var backgroundColor = configuration.widgetBackgroundColor.replace('#', '');

  // Generates a datatable for this specific source from the multi-source datatable.
  // The datatable is used to generate a table of the last 10 power values for the given source.
  // Column 0 contains the time in HH:MM:SS format.
  // Column 1 contains the power value associated with that timestamp.
  // Column 2 contains the change in power from the timestamp before this one. 
  function makeDataTable(rollingSecondsDatatable, source) {
    // Create the data table of power values to return.
    var powerTable = new google.visualization.DataTable();
    var numPowerTableRows = 10;
    powerTable.addColumn('date'); // the time of day.
    powerTable.addColumn('number'); // the power in Wh.
    powerTable.addColumn('number'); // the change in power, or blank if it's the last entry.
    powerTable.addRows(numPowerTableRows);
    // Determine the row in the rollingDays table that contains this source's data.
    var rollingPowerSourceRow = configuration.getRollingEnergyRow(source);
    // Initialize columns 0 and 1 for each of the 10 rows.
    for (var i = 0; i < numPowerTableRows; i++) {
      // Get the power value and timestamp.
      var offset = (i * 2) + 1;
      var timestampVal = rollingSecondsDatatable.getValue(rollingPowerSourceRow, offset);
      var powerVal = rollingSecondsDatatable.getValue(rollingPowerSourceRow, offset + 1);
      powerTable.setCell(i, 0, timestampVal);
      powerTable.setCell(i, 1, powerVal);
    }
    // Now initialize the change column for the first 9 rows.
    for (var i = 1; i < numPowerTableRows; i++) {
      var change = powerTable.getValue((i-1), 1) - powerTable.getValue(i, 1);
      powerTable.setCell((i - 1), 2, change);
    }
    // Now define formatters for the columns
    var dateFormatter = new google.visualization.DateFormat({pattern: 'h:mm:ss a'});
    dateFormatter.format(powerTable, 0);
    var formatter = new google.visualization.ArrowFormat();
    formatter.format(powerTable, 2); 
    return powerTable;
  }

  // Draws the three components (title, table, caption) of the energy
  // visualization.
  function draw(id, source, datatable) {
    // Get the short name associated with the source.
    var shortName = configuration.getSourceToShort(source);
    // Get the top-level div where this visualization should go.
    element = document.getElementById(id);
    // Now add the elements.
    addTopLevelStyle(element);
    addTitleDiv(element, id, shortName, datatable.getValue(0,0));
    addTableDiv(element, id, source, datatable);
    addSparklineDiv(element, id, datatable);
    addCaptionDiv(element, id, shortName, datatable);
  }

  // Adds 'global' CSS styling to the top-level div passed into this instance.
  function addTopLevelStyle(element) {
    element.style.backgroundColor = backgroundColor;
    element.style.margin = '0 auto';
    element.style.width = width + 'px';
  }

  function addTitleDiv(element, id, shortName, lastTimestamp) {
    var divId = id + '__Title';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    div.style.width = width + 'px';
    div.style.fontSize = '1.0em';
    div.style.fontWeight = 'bold';
    div.style.textAlign = 'center';
    div.style.color = configuration.widgetHeaderColor;
    var dateString = (lastTimestamp.toString()).substring(0, 15);
    div.innerHTML = 'Latest Power Data<br>' + shortName + '<br>' + dateString;
  }

  function addTableDiv(element, id, source, datatable) {
    var divId = id + '__Chart';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    var table = new org.wattdepot.gdata.HtmlTable();
    table.addAttribute('width=' + width + 'px');
    table.addAttribute('style="text-align: center"');
    table.addRow(['Time', 'Power (watts)', 'Change']);
    table.addTable(datatable, true);
    div.innerHTML = table.getHtml();
  }
  
  function addSparklineDiv(element, id, datatable) {
    var divId = id + '__Sparkline';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    div.style.backgroundColor = backgroundColor;
    var formatter = new google.visualization.ColorFormat();
    formatter.addRange(null, null, 'white', 'orange');
    formatter.format(datatable, 1);
    var view = new google.visualization.DataView(datatable);
    view.setColumns([1]);
    var chart = new google.visualization.LineChart(div);
    chart.draw(view, {vAxis : {minValue : 0}, curveType : 'function', pointSize : 0, legend: 'none', backgroundColor: backgroundColor, width: width, height: 40});
  }

  function addCaptionDiv(element, id, goal, shortName, datatable) {
    var divId = id + '__Caption';
    var div = getElementByIdOrCreate(divId, 'div');
    element.appendChild(div);
    div.style.color = configuration.widgetHeaderColor;
    div.innerHTML = 'Shows recent power values. "Change" column shows the change in power since the prior timestamp.';
  }

  // Returns the pre-existing element with id 'id', or else creates and returns
  // a new element with type elementType and that id.
  function getElementByIdOrCreate(id, elementType) {
    var element = document.getElementById(id);
    if (element) {
      return element;
    }
    else {
      element = document.createElement(elementType);
      element.setAttribute("id", id);
      return element;
    }
  }

  return {
    // Public interface to this function.
    draw : draw,
    makeDataTable : makeDataTable
  };
};
